import { Button, DatePicker, Form, Input, Select, TimePicker } from 'antd';
import React, { useEffect, useState } from 'react';
import RemoteSelect from '../../basic/RemoteSelect';
import styles from './index.module.sass';

const { RangePicker: TimeRangePicker } = TimePicker;
const { RangePicker: DateRangePicker } = DatePicker;

export enum QueryType {
    Default = 1,
    SimpleSelect,
    RemoteSelect,
    /**简单的日期选择 */
    SimpleDate,
    /**日期范围选择 */
    DateRangePicker,
    /**时间范围选择 */
    TimeRangePicker,
    /**日期时间范围选择 */
    DateTimeRangePicker,
    EmptyItem
}

/**输入控件的自定义选项，同时接管Form.Item的入参选项 */
interface Option {
    /**
     * 日期范围选择的格式化选项
     * true: 默认开始时间：startTime，YYYY-MM-DD HH:mm:ss，结束时间：endTime，YYYY-MM-DD HH:mm:ss
     * 数组: 下标0和1，作为格式化后开始和结束的请求参数，格式化模板默认为YYYY-MM-DD HH:mm:ss。
     *       ['startTime', 'endTime']
     * 对象: 第一组键值对的键为开始时间请求参数，值为开始时间格式化模板
     *       第二组键值对的键为结束时间请求参数，值为结束时间格式化模板
     *       {'startTime': 'YYYY-MM-DD HH:mm:ss'，'endTime': 'YYYY-MM-DD HH:mm:ss'}
     * 方法: 自定义处理，返回处理后的值。
     *       (val) => val
     */
    dateFormat?: Array<string> | Boolean | Function | Object[]

    /**接管Form.Item的入参选项 */
    formItem?: any

    /**组件内部扩展项 */
    [index: string]: any
}

interface Props {
    /**配置查询表单的数组项 */
    inputs: any[][]

    /**点击查询按钮的回调 */
    onSubmit?: Function

    /**点击重置按钮的回调 */
    onReset?: Function

    /**查询表单要装填的数据，设置查询表单的初始值 */
    queryData?: any

    /**经 Form.useForm() 创建的 form 控制实例 */
    formInstance?: any

    /**字段更新时触发回调事件 */
    onValuesChange?: Function
}

/**
 * 监听表单控件配置入参，生成ant实际使用的表单配置
 * @param inputs 配置入参
 * @param handle 表单配置的特殊处理
 * @returns 表单配置信息
 */
export function setInputConfig(inputs: any[][], handle?: Function) {
    return inputs.map(([label, key, ...item]: any) => {
        let type: QueryType = QueryType.Default,
            opt: Option = { formItem: {} };
        item.forEach((_item: any) => {
            if (QueryType[_item]) {
                type = _item;
            } else if (_.isObject(_item) && !Array.isArray(_item)) {
                Object.assign(opt, _item);
            }
        })
        if (handle) {
            return handle({ label, key, type, opt })
        } else {
            return { label, key, type, opt };
        }
    })
}

/**
 * 根据表单配置信息，对表单提交值进行相关处理
 * @param inputs 表单配置信息
 * @param values 表单提交原始值
 */
export function processSubmitValue(inputs: any, values: any) {
    const { key, type, opt } = inputs;
    /**日期范围选择的格式化处理 */
    if (type === QueryType.DateRangePicker) {
        if (values[key] && opt.dateFormat) {
            const { dateFormat } = opt;
            let startTime: string = 'startTime',
                endTime: string = 'endTime',
                startFormat = 'YYYY-MM-DD HH:mm:ss',
                endFormat: string = 'YYYY-MM-DD HH:mm:ss';
            if (Array.isArray(dateFormat)) {
                [startTime, endTime] = dateFormat;
            } else if (typeof dateFormat === 'function') {
                return dateFormat(values);
            } else if (_.isObject(dateFormat)) {
                [startTime, endTime] = Object.keys(dateFormat);
                [startFormat, endFormat] = Object.values(dateFormat);
            } else if (typeof dateFormat === 'boolean' && dateFormat) {

            } else {
                return;
            }
            values[startTime] = values[key][0].startOf('day').format(startFormat);
            values[endTime] = values[key][1].endOf('day').format(endFormat);
            values = _.omit(values, key);
        }
    }
    return values;
}

const QueryPanel: React.FC<Props> = ({
    inputs,
    onSubmit,
    onReset,
    queryData,
    formInstance,
    onValuesChange
}) => {
    console.debug('QueryPanel', inputs);

    const [form] = Form.useForm(formInstance);

    const [reset, setReset] = useState<number>(0);
    const [realInputs, setRealInputs] = useState<any[]>([]);
    const [formName] = useState<string>(() => Mock.Random.first());

    /**
     * 监听表单控件配置入参，生成ant实际使用的表单配置
     */
    useEffect(() => {
        if (inputs.length !== 0) {
            const _inputs = [];
            for (let i = 0; i < inputs.length; i++) {
                const item = inputs[i];

                let label: string, key: string;
                let type: QueryType = QueryType.Default,
                    opt: Option = { formItem: {} };

                /**
                 * 解构入参配置
                 */
                [label, key] = item;
                for (let index = 2; index < item.length; index++) {
                    const target = item[index];
                    if (QueryType[target]) { type = target }
                    else if (_.isObject(target)) { opt = { ...opt, ...target } }
                }
                _inputs.push({ label, key, type, opt });

            }

            /**
             * 解析表单项动态显示的标志
             */
            const allValues: any = {};
            _inputs.forEach((inp: any) => {
                allValues[inp.key] = inp.opt.formItem.initialValue
            });
            handleWhenFields(_inputs, allValues, false);

            setRealInputs(_inputs);
        }
    }, [inputs, reset])

    useEffect(() => {
        if (queryData && form) {
            form.setFieldsValue(queryData);
        }
    }, [form, queryData])

    function handleFinish(values: any) {
        onSubmit && onSubmit(values);
    }

    function handleReset() {
        form.resetFields();
        queryData && form.setFieldsValue(queryData);
        setReset((val) => ++val);
        onReset && onReset();
    }

    function handleValuesChange(changedValues: any, allValues: any) {
        handleWhenFields(realInputs, allValues, true);
        onValuesChange && onValuesChange(changedValues, allValues);
    }

    function handleWhenFields(_realInputs: any[], allValues: any, isSet: boolean) {
        const whenFieldList = _realInputs.filter(inp => inp.opt.whenFields);
        if (whenFieldList.length !== 0) {
            const hiddenList = [];
            const showList = [];
            whenFieldList.forEach((inp: any) => {
                let is = true;
                const whenFields = inp.opt.whenFields;
                const keys = _.keys(whenFields);
                for (let i = 0; i < keys.length; i++) {
                    const key = keys[i];
                    if (whenFields[key] !== allValues[key]) {
                        is = false;
                        break;
                    }
                }
                if (is && inp.opt.formItem.hidden === true) {
                    inp.opt.formItem.hidden = false;
                    inp.opt.formItem.rules = inp.opt.copyRules;
                    showList.push(inp);
                }
                if (!is && (inp.opt.formItem.hidden === false || _.isUndefined(inp.opt.formItem.hidden))) {
                    inp.opt.formItem.hidden = true;
                    inp.opt.copyRules = inp.opt.formItem.rules;
                    inp.opt.formItem.rules = undefined;
                    hiddenList.push(inp);
                }
            });
            if (isSet && (hiddenList.length !== 0 || showList.length !== 0)) {
                setRealInputs(_.clone(_realInputs));
            }
        }
    }

    return (
        <article>
            <Form
                name={formName}
                layout='inline'
                form={form}
                onFinish={handleFinish}
                onValuesChange={handleValuesChange}
            >
                {realInputs.map(({ label, key, type, opt }: any) => {

                    return (
                        <Form.Item
                            className={type === QueryType.EmptyItem ? styles.items : styles.item}
                            key={key}
                            label={label}
                            name={key}
                            {...opt.formItem}
                        >
                            {
                                (type === QueryType.Default &&
                                    <Input placeholder={opt?.placeholder || `输入${label}查询`} allowClear />
                                ) || (type === QueryType.SimpleSelect &&
                                    <Select
                                        className={styles.selectInpuut}
                                        placeholder={opt?.placeholder || `选择${label}查询`}
                                        disabled={opt.disabled}
                                        onChange={opt.onChange}
                                        allowClear={_.isUndefined(opt.allowClear) ? true : opt.allowClear}
                                        mode={opt.mode}
                                    >
                                        {opt.list && opt.list.map((it: any) =>
                                            <Select.Option key={it.value} value={it.value}>{it.name}</Select.Option>
                                        )}
                                    </Select>
                                ) || (type === QueryType.RemoteSelect &&
                                    <RemoteSelect
                                        placeholder={opt?.placeholder || `选择${label}查询`}
                                        remote={opt.remote}
                                        template={opt.template}
                                        isShowSearch={opt.isShowSearch}
                                        mode={opt.mode}
                                        allowClear={typeof opt.allowClear === 'boolean' ? opt.allowClear : true}
                                    />
                                ) || (type === QueryType.SimpleDate &&
                                    <DatePicker
                                        className={styles.simpleDate}
                                        placeholder={opt?.placeholder || `选择${label}查询`}
                                        allowClear={_.isUndefined(opt.allowClear) ? true : opt.allowClear}
                                        {...opt}
                                    />
                                ) || (type === QueryType.DateRangePicker &&
                                    <DateRangePicker
                                        {...opt}
                                        allowClear={_.isUndefined(opt.allowClear) ? true : opt.allowClear}
                                    />
                                ) || (type === QueryType.TimeRangePicker &&
                                    <TimeRangePicker
                                        allowClear={_.isUndefined(opt.allowClear) ? true : opt.allowClear}
                                    />
                                ) || (type === QueryType.DateTimeRangePicker &&
                                    <DateRangePicker
                                        allowClear={_.isUndefined(opt.allowClear) ? true : opt.allowClear}
                                        showTime
                                    />
                                ) || (type === QueryType.EmptyItem && <React.Fragment></React.Fragment>)
                            }
                        </Form.Item>
                    )
                })}
                <Form.Item className={styles.item}>
                    <Button className={styles.submit} type="primary" htmlType="submit">
                        查询
                    </Button>
                    <Button className={styles.reset} onClick={handleReset} >
                        重置
                    </Button>
                </Form.Item>
            </Form>
        </article>
    )
}

export default QueryPanel;